#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

// #define I(i,n) for(int i=0;i<n;++i)

class Record // 学生
{
public:
	string id;
	string name;
};

ostream & operator << (ostream & o, const Record & r) {
	o << "姓名:" << r.name << ", 学号:" << r.id;
	return o;
}

int parse_int(const string & text) {
	if (text[0]=='-')
		return -parse_int(text.substr(1));
	int val = 0;
	I(i, text.size()) {
		if (text[i]<'0' or text[i]>'9') break;
		val = val * 10 + (text[i]-'0');
	}
	return val;
}

int get_choice(int min, int max) {
	while (true) {
		cout << "请选择:";
		string choice_text;
		cin >> choice_text;
		int choice = parse_int(choice_text);
		if (choice >= min and choice <= max) return choice;
		cout << "没有这个选项 " << choice <<", 请重新选择 !" << endl;
	}
}

class InfoSys // 同学录
{
public:
	vector<Record> records;

	void load() {
		ifstream fin("../../info.txt");
		if (fin.fail()) {
			cerr << "读方式打开文件失败: info.txt\n";
			return;
		}
		while (fin) {
			Record r;
			fin >> r.id;
			fin >> r.name;
			if (! fin) break;
			records.push_back(r);
		}
		fin.close();
	}

	void save() {
		ofstream fout("../../info.txt");
		if (fout.fail()) {
			cerr << "写方式打开文件失败: info.txt\n";
			return;
		}
		I(i, records.size())
			fout << records[i].id << "\t"
				<< records[i].name << "\n";
		fout.close();
	}

	InfoSys() {
		load();
	}

	~InfoSys() {
		save();
	}

	vector<int> find(const string & attr, 
					const string & val) {
		vector<int> res;
		if (attr=="姓名")
			I(i, records.size())
				if (records[i].name==val)
					res.push_back(i);
		if (attr=="学号")
			I(i, records.size())
				if (records[i].id==val)
					res.push_back(i);
		return res;
	}

	bool _add_record(const string & action, const Record & r) {
		if (r.name == "")
			cout << "姓名不能为空, "<<action<<"失败 !\n";
		else if (r.id == "") 
			cout << "学号不能为空, "<<action<<"失败 !\n";
		else if (find("姓名", r.name).size()>0)
			cout << "该姓名已经存在, "<<action<<"失败 !\n";
		else if (find("学号", r.id).size()>0) 
			cout << "该学号已经存在, "<<action<<"失败 !\n";
		else {
			records.push_back(r);
			return true;
		}
		return false;
	}

	int show_main_menu(string record_name="同学") {
		cout << "主菜单:\n";
		cout << "1. 添加" << record_name << "\n";
		cout << "2. 删除" << record_name << "\n";
		cout << "3. 更新" << record_name << "\n";
		cout << "4. 查找" << record_name << "\n";
		cout << "5. 退出程序" << "\n";
		return get_choice(1,5);
	}

	void add_record() {
		cout << "你选择了添加同学，请根据提示输入所需信息" << endl;
		Record r;
		cout << "姓名:";
		cin >> r.name;
		cout << "学号:";
		cin >> r.id;
		if (_add_record("添加", r))
			cout << "添加成功 :)";
	}

	bool get_attr_val(string & attr, string & val,
						const string & action, 
						const string & record_name="同学") {
		cout << "1. 姓名\n";
		cout << "2. 学号\n";
		cout << "3. 取消" << action << record_name << "\n";
		int choice = get_choice(1,3);
		if (choice==3) return false;
		attr = (choice==1 ? "姓名" : "学号");
		cout << "请输入待"<<action<<"的"<<record_name<<"的"<<attr<< ":";
		cin >> val;
		return true;
	}

	vector<int> search_records(string action="查找", string record_name="同学") {
		cout << "你选择了"<<action<<record_name<<"，选择"<<action<<"所使用的属性" << endl;
		string attr, val;
		if (! get_attr_val(attr, val, action))
			return vector<int>();
		vector<int> indexes = find(attr, val);
		if (indexes.size()==0) {
			cout << "不存在"<<attr<<"为"<<val<<"的"<<record_name<<"，"<<action<<"失败 !\n";
		}
		else {
			I(i, indexes.size())
				cout << records[indexes[i]] << endl;
		}
		return indexes;
	}

	void _del_record(int index) {
		swap(records[index], records[records.size()-1]);
		records.pop_back();
	}

	void del_records(const string & record_name="同学") {
		vector<int> indexes = search_records("删除");
		int n = indexes.size();
		if (n==0) return;
		I(i, n)
			_del_record(indexes[n-1-i]);
		cout << "已删除以上"<<indexes.size()<<"个" << record_name << endl;		
	}

	void update_record() {
		vector<int> indexes = search_records("更新");
		int n = indexes.size();
		if (n==0) return;
		cout << "选择要被更新的属性" << endl;
		string attr, val;
		if (not get_attr_val(attr, val, "更新"))
			return;
		n = indexes.size();
		I(i, n) {
			Record r = records[indexes[n-1-i]];
			_del_record(indexes[n-1-i]);
			Record new_r(r);
			if (attr=="姓名")
				new_r.name = val;
			if (attr=="学号")
				new_r.id = val;
			if (_add_record("更新", new_r))
				cout << r << " 已更新为 " << new_r << endl;
			else {
				_add_record("更新", r);
				cout << r << " 不能被更新为 " << new_r << endl;
			}
		}

	}

	void run_main_menu() {
		while (true) {
			int choice = show_main_menu();
			if (choice == 5) break;
			switch (choice) {
			case 1: add_record(); break;
			case 2: del_records(); break;
			case 3: update_record(); break;
			case 4: search_records(); break;
			}
		}		
	}

};

// int main() {
// 	InfoSys s;
// 	s.run_main_menu();
// }